#ifndef __BUILDER_HPP__
#define __BUILDER_HPP__

#include <string>
#include <map>
#include <memory>

#include "metrics/MetricRegistry.hpp"

namespace metrics
{
    template <typename T>
    class Family;

    //metrics 构建器
    template <typename T>
    class Builder
    {
    protected:
        std::string _name;
        std::string _help;
        std::map<std::string, std::string> _labels;

    public:
        Builder();
        Builder(const std::string &name, const std::string &help, const std::map<std::string, std::string> &labels);
        virtual ~Builder();

        virtual Builder &labels(const std::map<std::string, std::string> &labels);
        virtual Builder &name(const std::string &);
        virtual Builder &help(const std::string &);
        std::shared_ptr<Family<T>> metric_register(std::shared_ptr<MetricRegistry> registry);
    };

    template <typename T>
    Builder<T>::Builder()
    {
    }

    template <typename T>
    Builder<T>::Builder(const std::string &name, const std::string &help, const std::map<std::string, std::string> &labels)
        : _name(name), _help(help), _labels(labels)
    {
    }

    template <typename T>
    Builder<T>::~Builder()
    {
    }

    template <typename T>
    Builder<T> &Builder<T>::labels(const std::map<std::string, std::string> &labels)
    {
        _labels = labels;
        return *this;
    }

    template <typename T>
    Builder<T> &Builder<T>::name(const std::string &name)
    {
        _name = name;
        return *this;
    }

    template <typename T>
    Builder<T> &Builder<T>::help(const std::string &help)
    {
        _help = help;
        return *this;
    }

    template <typename T>
    std::shared_ptr<Family<T>> Builder<T>::metric_register(std::shared_ptr<MetricRegistry> registry)
    {
        return registry->add<T>(_name, _help, _labels);
    }

    Builder<Counter> BuildCounter();
    Builder<Gauge> BuildGauge();
    Builder<Histogram> BuildHistogram();
} // namespace metrics

#endif // __BUILDER_HPP__